package com.ccrfid.rmc6.service.poi;

import com.ccrfid.rmc6.entity.device.LocatorEntity;
import com.ccrfid.rmc6.entity.personnel.PersonnelView;
import com.ccrfid.rmc6.entity.poi.PoiLocationEntity;
import com.ccrfid.rmc6.entity.video.VideoCameraView;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
import java.util.List;

@Service
@Transactional
public class PoiServiceImpl implements PoiService {
    private static final Logger logger = LoggerFactory.getLogger(PoiServiceImpl.class);
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List<PoiLocationEntity> getPoiLocationsInPolygon(Integer mapLevel, Integer floorNumber, Polygon polygon) {
        String sql = "select * from poi_location p where p.map_level = '" + mapLevel + "' ";
        if (floorNumber != null) {
            sql += "and p.floor_number = '" + floorNumber + "' ";
        }
        sql += "and st_contains(:pg, p.location_centroid)";
        List<PoiLocationEntity> list = entityManager.createNativeQuery(sql, PoiLocationEntity.class)
                .setParameter("pg", polygon)
                .getResultList();
        return list;
    }

    @Override
    public List<LocatorEntity> getLocatorsInLocation(PoiLocationEntity locationEntity) {
        String sql = "SELECT * FROM d_locator d ";
        if (locationEntity.getFloorNumber() != null) {
            sql += "WHERE d.floor_number = '" + locationEntity.getFloorNumber() + "' and st_contains(:pg, d.pos)";
        } else {
            sql += "WHERE st_contains(:pg, d.pos)";
        }
        List<LocatorEntity> list = entityManager.createNativeQuery(sql, LocatorEntity.class)
                .setParameter("pg", locationEntity.getLocationPolygon())
                .getResultList();
        return list;
    }

    @Override
    public List<PoiLocationEntity> getLocationsByLocator(LocatorEntity locatorEntity) {
        String sql = "SELECT * FROM poi_location p ";
        if (locatorEntity.getFloorNumber() != null) {
            sql += "WHERE p.floor_number = '" + locatorEntity.getFloorNumber() + "' and st_contains(p.location_polygon, :pt)";
        } else {
            sql += "WHERE st_contains(p.location_polygon, :pt)";
        }
        List<PoiLocationEntity> list = entityManager.createNativeQuery(sql, PoiLocationEntity.class)
                .setParameter("pt", locatorEntity.getPos()).getResultList();
        return list;
    }

    @Override
    public PoiLocationEntity get3LevelLocationByPos(Integer floorNumber, Point point) {
        if (floorNumber != null && point != null) {
            String sql = "SELECT * FROM poi_location p WHERE p.map_level = 3 AND p.floor_number = '" + floorNumber
                    + "' and st_contains(p.location_polygon, :pt)";

            List<PoiLocationEntity> list = entityManager.createNativeQuery(sql, PoiLocationEntity.class)
                    .setParameter("pt", point).getResultList();
            if (list.size() > 0) {
                return list.get(0);
            } else {
                return null;
            }
        }
        return null;
    }

    @Override
    public List<VideoCameraView> getCamerasInLocation(PoiLocationEntity locationEntity) {
        String sql = "SELECT * FROM v_video_camera v WHERE v.floor_number = '" + locationEntity.getFloorNumber()
                + "' and st_contains(:pg, v.pos)";
        List<VideoCameraView> list = entityManager.createNativeQuery(sql, VideoCameraView.class)
                .setParameter("pg", locationEntity.getLocationPolygon())
                .getResultList();
        return list;
    }

    @Override
    public List<VideoCameraView> getCamerasInPolygon(Integer floorNumber, Polygon polygon) {
        String sql = "SELECT * FROM v_video_camera v WHERE v.floor_number = '" + floorNumber
                + "' and st_contains(:pg, v.pos)";
        List<VideoCameraView> list = entityManager.createNativeQuery(sql, VideoCameraView.class)
                .setParameter("pg", polygon)
                .getResultList();
        return list;
    }

    @Override
    public List<PersonnelView> getPersonnelsInLocation(PoiLocationEntity locationEntity) {
        String sql = "SELECT * FROM v_personnel v WHERE v.is_enabled = 1 and v.floor_number = '"
                + locationEntity.getFloorNumber() + "' and st_contains(:pg, v.pos)";
        List<PersonnelView> list = entityManager.createNativeQuery(sql, PersonnelView.class)
                .setParameter("pg", locationEntity.getLocationPolygon())
                .getResultList();
        return list;
    }
}
